Simplify APIC_ACCESS VMX support.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 30 May 2007 16:01:26 +0000 (17:01 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 30 May 2007 16:01:26 +0000 (17:01 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
12 files changed:
xen/arch/x86/domain.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/intr.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/domain.h
xen/include/asm-x86/hvm/hvm.h
xen/include/asm-x86/hvm/vlapic.h
xen/include/asm-x86/hvm/vmx/vmcs.h
xen/include/asm-x86/hvm/vmx/vmx.h
xen/include/asm-x86/msr.h

index 085e90d4dab31a2150b6b6d7272bd1c89b480b15..c0e0b0c56e7dcf68e3d21e637a9efadc8491ef28 100644 (file)
@@ -393,7 +393,7 @@ int arch_domain_create(struct domain *d)
     int i;
 #endif
     l1_pgentry_t gdt_l1e;
-    int vcpuid, pdpt_order;
+    int vcpuid, pdpt_order, paging_initialised = 0;
     int rc = -ENOMEM;
 
     pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
@@ -442,6 +442,7 @@ int arch_domain_create(struct domain *d)
 #endif
 
     paging_domain_init(d);
+    paging_initialised = 1;
 
     if ( !is_idle_domain(d) )
     {
@@ -469,12 +470,13 @@ int arch_domain_create(struct domain *d)
         d->arch.is_32bit_pv = d->arch.has_32bit_shinfo =
             (CONFIG_PAGING_LEVELS != 4);
     }
-        
 
     return 0;
 
  fail:
     free_xenheap_page(d->shared_info);
+    if ( paging_initialised )
+        paging_final_teardown(d);
 #ifdef __x86_64__
     if ( d->arch.mm_perdomain_l2 )
         free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
index c3e5ebe3e668179daa3159bd1d9139fbd8352967..464e9fdb872e260df3d42de7e10aac65a1f6dec7 100644 (file)
@@ -226,7 +226,6 @@ int hvm_domain_initialise(struct domain *d)
 
     spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
     spin_lock_init(&d->arch.hvm_domain.irq_lock);
-    spin_lock_init(&d->arch.hvm_domain.vapic_access_lock);
 
     rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
     if ( rc != 0 )
@@ -238,7 +237,7 @@ int hvm_domain_initialise(struct domain *d)
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 
-    return 0;
+    return hvm_funcs.domain_initialise(d);
 }
 
 void hvm_domain_relinquish_resources(struct domain *d)
@@ -249,10 +248,7 @@ void hvm_domain_relinquish_resources(struct domain *d)
 
 void hvm_domain_destroy(struct domain *d)
 {
-    pit_deinit(d);
-    rtc_deinit(d);
-    pmtimer_deinit(d);
-    hpet_deinit(d);
+    hvm_funcs.domain_destroy(d);
 }
 
 static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
@@ -409,27 +405,39 @@ int hvm_vcpu_initialise(struct vcpu *v)
 
     INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
 
-    if ( v->vcpu_id != 0 )
-        return 0;
-
-    pit_init(v, cpu_khz);
-    rtc_init(v, RTC_PORT(0));
-    pmtimer_init(v);
-    hpet_init(v);
+    if ( v->vcpu_id == 0 )
+    {
+        /* NB. All these really belong in hvm_domain_initialise(). */
+        pit_init(v, cpu_khz);
+        rtc_init(v, RTC_PORT(0));
+        pmtimer_init(v);
+        hpet_init(v);
  
-    /* Init guest TSC to start from zero. */
-    hvm_set_guest_time(v, 0);
+        /* Init guest TSC to start from zero. */
+        hvm_set_guest_time(v, 0);
+    }
 
     return 0;
 }
 
 void hvm_vcpu_destroy(struct vcpu *v)
 {
+    struct domain *d = v->domain;
+
     vlapic_destroy(v);
     hvm_funcs.vcpu_destroy(v);
 
     /* Event channel is already freed by evtchn_destroy(). */
     /*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/
+
+    if ( v->vcpu_id == 0 )
+    {
+        /* NB. All these really belong in hvm_domain_destroy(). */
+        pit_deinit(d);
+        rtc_deinit(d);
+        pmtimer_deinit(d);
+        hpet_deinit(d);
+    }
 }
 
 
index 669fa4b7db13510e626460a3fdd21d83d2a6245b..27e6d1c8f6e313aae07a194d02b3638afae6bdea 100644 (file)
@@ -876,6 +876,15 @@ static void svm_do_resume(struct vcpu *v)
     reset_stack_and_jump(svm_asm_do_resume);
 }
 
+static int svm_domain_initialise(struct domain *d)
+{
+    return 0;
+}
+
+static void svm_domain_destroy(struct domain *d)
+{
+}
+
 static int svm_vcpu_initialise(struct vcpu *v)
 {
     int rc;
@@ -920,6 +929,8 @@ static int svm_event_injection_faulted(struct vcpu *v)
 static struct hvm_function_table svm_function_table = {
     .name                 = "SVM",
     .disable              = stop_svm,
+    .domain_initialise    = svm_domain_initialise,
+    .domain_destroy       = svm_domain_destroy,
     .vcpu_initialise      = svm_vcpu_initialise,
     .vcpu_destroy         = svm_vcpu_destroy,
     .store_cpu_guest_regs = svm_store_cpu_guest_regs,
index 9119cfbf221cc84d5eb9f5320dfa97e000f7214b..b50dcf868a11402ef2fac61b5dd7e69ed0d1afdb 100644 (file)
@@ -74,11 +74,6 @@ static void update_tpr_threshold(struct vlapic *vlapic)
     if ( !cpu_has_vmx_tpr_shadow )
         return;
 
-#ifdef __i386__
-    if ( !vlapic->mmap_vtpr_enabled )
-        return;
-#endif
-
     if ( !vlapic_enabled(vlapic) || 
          ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
     {
index ee5f437797efd7ec22641eb8105205ba6fc1a00d..7d263985f8f309d68425fc89ab2d1a7d47d896b7 100644 (file)
@@ -61,9 +61,6 @@ static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr)
     return ctl;
 }
 
-#define vmx_has_secondary_exec_ctls \
-    (_vmx_cpu_based_exec_control & ACTIVATE_SECONDARY_CONTROLS)
-
 void vmx_init_vmcs_config(void)
 {
     u32 vmx_msr_low, vmx_msr_high, min, opt;
@@ -76,7 +73,7 @@ void vmx_init_vmcs_config(void)
     min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
     opt = 0;
     _vmx_pin_based_exec_control = adjust_vmx_controls(
-        min, opt, MSR_IA32_VMX_PINBASED_CTLS_MSR);
+        min, opt, MSR_IA32_VMX_PINBASED_CTLS);
 
     min = (CPU_BASED_HLT_EXITING |
            CPU_BASED_INVDPG_EXITING |
@@ -84,24 +81,21 @@ void vmx_init_vmcs_config(void)
            CPU_BASED_MOV_DR_EXITING |
            CPU_BASED_ACTIVATE_IO_BITMAP |
            CPU_BASED_USE_TSC_OFFSETING);
-    opt = CPU_BASED_ACTIVATE_MSR_BITMAP;
+    opt  = CPU_BASED_ACTIVATE_MSR_BITMAP;
     opt |= CPU_BASED_TPR_SHADOW;
-    opt |= ACTIVATE_SECONDARY_CONTROLS;
+    opt |= CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
     _vmx_cpu_based_exec_control = adjust_vmx_controls(
-        min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+        min, opt, MSR_IA32_VMX_PROCBASED_CTLS);
 #ifdef __x86_64__
     if ( !(_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) )
     {
         min |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
         _vmx_cpu_based_exec_control = adjust_vmx_controls(
-            min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+            min, opt, MSR_IA32_VMX_PROCBASED_CTLS);
     }
-#elif defined(__i386__)
-    if ( !vmx_has_secondary_exec_ctls )
-        _vmx_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
 #endif
 
-    if ( vmx_has_secondary_exec_ctls )
+    if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )
     {
         min = 0;
         opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
@@ -109,27 +103,33 @@ void vmx_init_vmcs_config(void)
             min, opt, MSR_IA32_VMX_PROCBASED_CTLS2);
     }
 
+#if defined(__i386__)
+    /* If we can't virtualise APIC accesses, the TPR shadow is pointless. */
+    if ( !(_vmx_secondary_exec_control &
+           SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) )
+        _vmx_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
+#endif
+
     min = VM_EXIT_ACK_INTR_ON_EXIT;
     opt = 0;
 #ifdef __x86_64__
     min |= VM_EXIT_IA32E_MODE;
 #endif
     _vmx_vmexit_control = adjust_vmx_controls(
-        min, opt, MSR_IA32_VMX_EXIT_CTLS_MSR);
+        min, opt, MSR_IA32_VMX_EXIT_CTLS);
 
     min = opt = 0;
     _vmx_vmentry_control = adjust_vmx_controls(
-        min, opt, MSR_IA32_VMX_ENTRY_CTLS_MSR);
+        min, opt, MSR_IA32_VMX_ENTRY_CTLS);
 
-    rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
+    rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
 
     if ( smp_processor_id() == 0 )
     {
         vmcs_revision_id = vmx_msr_low;
         vmx_pin_based_exec_control = _vmx_pin_based_exec_control;
         vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
-        if ( vmx_has_secondary_exec_ctls )
-            vmx_secondary_exec_control = _vmx_secondary_exec_control;
+        vmx_secondary_exec_control = _vmx_secondary_exec_control;
         vmx_vmexit_control         = _vmx_vmexit_control;
         vmx_vmentry_control        = _vmx_vmentry_control;
     }
@@ -138,8 +138,7 @@ void vmx_init_vmcs_config(void)
         BUG_ON(vmcs_revision_id != vmx_msr_low);
         BUG_ON(vmx_pin_based_exec_control != _vmx_pin_based_exec_control);
         BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control);
-        if ( vmx_has_secondary_exec_ctls )
-            BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control);
+        BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control);
         BUG_ON(vmx_vmexit_control != _vmx_vmexit_control);
         BUG_ON(vmx_vmentry_control != _vmx_vmentry_control);
     }
@@ -310,7 +309,7 @@ static void construct_vmcs(struct vcpu *v)
     __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
     __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
     v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
-    if ( vmx_cpu_based_exec_control & ACTIVATE_SECONDARY_CONTROLS )
+    if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )
         __vmwrite(SECONDARY_VM_EXEC_CONTROL, vmx_secondary_exec_control);
 
     if ( cpu_has_vmx_msr_bitmap )
@@ -437,24 +436,14 @@ static void construct_vmcs(struct vcpu *v)
         cr4 & ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
     __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
 
-#ifdef __x86_64__ 
-    /* CR8 based VLAPIC TPR optimization. */
     if ( cpu_has_vmx_tpr_shadow )
     {
-        __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
-                  page_to_maddr(vcpu_vlapic(v)->regs_page));
-        __vmwrite(TPR_THRESHOLD, 0);
-    }
+        uint64_t virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
+#if defined (__i386__)
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
 #endif
-
-    /* Memory-mapped based VLAPIC TPR optimization. */
-    if ( cpu_has_vmx_mmap_vtpr_optimization )
-    {
-        __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
-                    page_to_maddr(vcpu_vlapic(v)->regs_page));
         __vmwrite(TPR_THRESHOLD, 0);
-
-        vcpu_vlapic(v)->mmap_vtpr_enabled = 1;
     }
 
     __vmwrite(GUEST_LDTR_SELECTOR, 0);
@@ -527,18 +516,6 @@ void vmx_do_resume(struct vcpu *v)
         vmx_set_host_env(v);
     }
 
-    if ( !v->arch.hvm_vmx.launched && vcpu_vlapic(v)->mmap_vtpr_enabled )
-    {
-        struct page_info *pg = change_guest_physmap_for_vtpr(v->domain, 1);
-
-        if ( pg == NULL )
-        {
-            gdprintk(XENLOG_ERR, "change_guest_physmap_for_vtpr failed!\n");
-            domain_crash_synchronous();
-        }
-        __vmwrite(APIC_ACCESS_ADDR, page_to_maddr(pg));
-    }
-
     debug_state = v->domain->debugger_attached;
     if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
     {
index c77092204f19661fde5ca1686424bd9cb6da165f..9d8ba90d0f35c29d360f9741df9e75d1130eeaa9 100644 (file)
@@ -56,6 +56,20 @@ char *vmx_msr_bitmap;
 static void vmx_ctxt_switch_from(struct vcpu *v);
 static void vmx_ctxt_switch_to(struct vcpu *v);
 
+static int  vmx_alloc_vlapic_mapping(struct domain *d);
+static void vmx_free_vlapic_mapping(struct domain *d);
+static void vmx_install_vlapic_mapping(struct vcpu *v);
+
+static int vmx_domain_initialise(struct domain *d)
+{
+    return vmx_alloc_vlapic_mapping(d);
+}
+
+static void vmx_domain_destroy(struct domain *d)
+{
+    vmx_free_vlapic_mapping(d);
+}
+
 static int vmx_vcpu_initialise(struct vcpu *v)
 {
     int rc;
@@ -74,6 +88,8 @@ static int vmx_vcpu_initialise(struct vcpu *v)
         return rc;
     }
 
+    vmx_install_vlapic_mapping(v);
+
     return 0;
 }
 
@@ -1168,6 +1184,8 @@ static void disable_intercept_for_msr(u32 msr)
 static struct hvm_function_table vmx_function_table = {
     .name                 = "VMX",
     .disable              = stop_vmx,
+    .domain_initialise    = vmx_domain_initialise,
+    .domain_destroy       = vmx_domain_destroy,
     .vcpu_initialise      = vmx_vcpu_initialise,
     .vcpu_destroy         = vmx_vcpu_destroy,
     .store_cpu_guest_regs = vmx_store_cpu_guest_regs,
@@ -2483,112 +2501,66 @@ done:
     return 1;
 }
 
-struct page_info * change_guest_physmap_for_vtpr(struct domain *d,
-                                                 int enable_vtpr)
+static int vmx_alloc_vlapic_mapping(struct domain *d)
 {
-    struct page_info *pg;
-    unsigned long pfn, mfn;
-
-    spin_lock(&d->arch.hvm_domain.vapic_access_lock);
-
-    pg = d->arch.hvm_domain.apic_access_page;
-    pfn = paddr_to_pfn(APIC_DEFAULT_PHYS_BASE);
-
-    if ( enable_vtpr )
-    {
-        if ( d->arch.hvm_domain.physmap_changed_for_vlapic_access )
-            goto out;
-
-        if ( pg == NULL )
-            pg = alloc_domheap_page(d);
-        if ( pg == NULL )
-        {
-            gdprintk(XENLOG_ERR, "alloc_domheap_pages() failed!\n");
-            goto out;
-        }
+    void *apic_va;
 
-        mfn = page_to_mfn(pg);
-        d->arch.hvm_domain.apic_access_page = pg;
-
-        guest_physmap_add_page(d, pfn, mfn);
+    if ( !cpu_has_vmx_virtualize_apic_accesses )
+        return 0;
 
-        d->arch.hvm_domain.physmap_changed_for_vlapic_access = 1;
+    apic_va = alloc_xenheap_page();
+    if ( apic_va == NULL )
+        return -ENOMEM;
+    share_xen_page_with_guest(virt_to_page(apic_va), d, XENSHARE_writable);
+    guest_physmap_add_page(
+        d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), virt_to_mfn(apic_va));
+    d->arch.hvm_domain.vmx_apic_access_mfn = virt_to_mfn(apic_va);
 
-        goto out;
-    }
-    else
-    {
-        if ( d->arch.hvm_domain.physmap_changed_for_vlapic_access )
-        {
-            mfn = page_to_mfn(pg);
-            guest_physmap_remove_page(d, pfn, mfn);
-            flush_tlb_mask(d->domain_dirty_cpumask);
-
-            d->arch.hvm_domain.physmap_changed_for_vlapic_access = 0;
-        }
-        pg = NULL;
-        goto out;
-    }
+    return 0;
+}
 
-out:
-    spin_unlock(&d->arch.hvm_domain.vapic_access_lock);
-    return pg;
+static void vmx_free_vlapic_mapping(struct domain *d)
+{
+    unsigned long mfn = d->arch.hvm_domain.vmx_apic_access_mfn;
+    if ( mfn != 0 )
+        free_xenheap_page(mfn_to_virt(mfn));
 }
 
-static void check_vlapic_msr_for_vtpr(struct vcpu *v)
+static void vmx_install_vlapic_mapping(struct vcpu *v)
 {
-    struct vlapic *vlapic = vcpu_vlapic(v);
-    int    mmap_vtpr_enabled = vcpu_vlapic(v)->mmap_vtpr_enabled;
-    uint32_t tmp;
+    paddr_t virt_page_ma, apic_page_ma;
 
+    if ( !cpu_has_vmx_virtualize_apic_accesses )
+        return;
 
-    if ( vlapic_hw_disabled(vlapic) && mmap_vtpr_enabled )
-    {
-        vcpu_vlapic(v)->mmap_vtpr_enabled = 0;    
+    virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
+    apic_page_ma = v->domain->arch.hvm_domain.vmx_apic_access_mfn;
+    apic_page_ma <<= PAGE_SHIFT;
 
-#ifdef __i386__
-        v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
-        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                  v->arch.hvm_vcpu.u.vmx.exec_control);
-#elif defined(__x86_64__)
-        if ( !cpu_has_vmx_tpr_shadow )
-        {
-            v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
-            __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                v->arch.hvm_vcpu.u.vmx.exec_control);
-        }
+    vmx_vmcs_enter(v);
+    __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
+    __vmwrite(APIC_ACCESS_ADDR, apic_page_ma);
+#if defined (__i386__)
+    __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
+    __vmwrite(APIC_ACCESS_ADDR_HIGH, apic_page_ma >> 32);
 #endif
-        tmp  = __vmread(SECONDARY_VM_EXEC_CONTROL);
-        tmp &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
-        __vmwrite(SECONDARY_VM_EXEC_CONTROL, tmp);
-
-        change_guest_physmap_for_vtpr(v->domain, 0);
-    }
-    else if ( !vlapic_hw_disabled(vlapic) && !mmap_vtpr_enabled &&
-              cpu_has_vmx_mmap_vtpr_optimization )
-    {
-        vcpu_vlapic(v)->mmap_vtpr_enabled = 1;
+    vmx_vmcs_exit(v);
+}
 
-        v->arch.hvm_vcpu.u.vmx.exec_control |=
-            ( ACTIVATE_SECONDARY_CONTROLS | CPU_BASED_TPR_SHADOW );
-        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                  v->arch.hvm_vcpu.u.vmx.exec_control);
-        tmp  = __vmread(SECONDARY_VM_EXEC_CONTROL);
-        tmp |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
-        __vmwrite(SECONDARY_VM_EXEC_CONTROL, tmp);
+static void vmx_check_vlapic_msr(struct vcpu *v)
+{
+    struct vlapic *vlapic = vcpu_vlapic(v);
+    uint32_t ctl;
 
-        change_guest_physmap_for_vtpr(v->domain, 1);
-    }
+    if ( !cpu_has_vmx_virtualize_apic_accesses )
+        return;
 
-    if ( vcpu_vlapic(v)->mmap_vtpr_enabled &&
-        !vlapic_hw_disabled(vlapic) &&
-        (vlapic_base_address(vlapic) != APIC_DEFAULT_PHYS_BASE) )
-    {
-        gdprintk(XENLOG_ERR,
-                 "Local APIC base address is set to 0x%016"PRIx64"!\n",
-                  vlapic_base_address(vlapic));
-        domain_crash_synchronous();
-    }
+    ctl  = __vmread(SECONDARY_VM_EXEC_CONTROL);
+    ctl &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+    if ( !vlapic_hw_disabled(vlapic) &&
+         (vlapic_base_address(vlapic) == APIC_DEFAULT_PHYS_BASE) )
+        ctl |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+    __vmwrite(SECONDARY_VM_EXEC_CONTROL, ctl);
 }
 
 static inline int vmx_do_msr_write(struct cpu_user_regs *regs)
@@ -2619,7 +2591,7 @@ static inline int vmx_do_msr_write(struct cpu_user_regs *regs)
         break;
     case MSR_IA32_APICBASE:
         vlapic_msr_set(vcpu_vlapic(v), msr_content);
-        check_vlapic_msr_for_vtpr(v);
+        vmx_check_vlapic_msr(v);
         break;
     default:
         if ( !long_mode_do_msr_write(regs) )
@@ -2932,12 +2904,12 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
 
     case EXIT_REASON_TPR_BELOW_THRESHOLD:
         break;
+
     case EXIT_REASON_APIC_ACCESS:
     {
         unsigned long offset;
-
         exit_qualification = __vmread(EXIT_QUALIFICATION);
-        offset = exit_qualification & 0x0fffUL;        
+        offset = exit_qualification & 0x0fffUL;
         handle_mmio(APIC_DEFAULT_PHYS_BASE | offset);
         break;
     }
index 191deac3814bd5b32543952337059201ca4b7fbf..20fca664b5dc53968c88ba4b4ae8584d3f56d8ac 100644 (file)
@@ -41,11 +41,6 @@ struct hvm_domain {
     s64                    tsc_frequency;
     struct pl_time         pl_time;
 
-    /* For memory-mapped vLAPIC/vTPR access optimization */
-    spinlock_t             vapic_access_lock;
-    int                    physmap_changed_for_vlapic_access : 1;
-    struct page_info       *apic_access_page;
-
     struct hvm_io_handler  io_handler;
 
     /* Lock protects access to irq, vpic and vioapic. */
@@ -60,6 +55,8 @@ struct hvm_domain {
     spinlock_t             pbuf_lock;
 
     uint64_t               params[HVM_NR_PARAMS];
+
+    unsigned long          vmx_apic_access_mfn;
 };
 
 #endif /* __ASM_X86_HVM_DOMAIN_H__ */
index a89f242cbe69b7e5feab48e82648ae905f83e991..0a976e67b2788fb114dbfc64e307509697b33627 100644 (file)
@@ -69,8 +69,10 @@ struct hvm_function_table {
     void (*disable)(void);
 
     /*
-     * Initialise/destroy HVM VCPU resources
+     * Initialise/destroy HVM domain/vcpu resources
      */
+    int  (*domain_initialise)(struct domain *d);
+    void (*domain_destroy)(struct domain *d);
     int  (*vcpu_initialise)(struct vcpu *v);
     void (*vcpu_destroy)(struct vcpu *v);
 
index 80cd32ec569b206969c0bf550f7b50e2cdb6dc5d..ed4fe172b7c33bacd92735a1f9e8ce48b6c1f4e8 100644 (file)
@@ -33,7 +33,7 @@
 #define vlapic_domain(vpic) (vlapic_vcpu(vlapic)->domain)
 
 #define VLAPIC_ID(vlapic)   \
-    (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)))
+    (GET_APIC_ID(vlapic_get_reg((vlapic), APIC_ID)))
 
 /*
  * APIC can be disabled in two ways:
@@ -50,7 +50,7 @@
 #define vlapic_enabled(vlapic)     (!vlapic_disabled(vlapic))
 
 #define vlapic_base_address(vlapic)                             \
-    (vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
+    ((vlapic)->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
 
 struct vlapic {
     struct hvm_hw_lapic      hw;
@@ -58,8 +58,6 @@ struct vlapic {
     struct periodic_time     pt;
     s_time_t                 timer_last_update;
     struct page_info         *regs_page;
-
-    int                      mmap_vtpr_enabled : 1;
 };
 
 static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg)
index 449afd11cf2bfda19f7a70f300872f9e856ac5eb..93383559c518ae3cbb13281e03fb59a3197b60b5 100644 (file)
@@ -90,23 +90,23 @@ void vmx_destroy_vmcs(struct vcpu *v);
 void vmx_vmcs_enter(struct vcpu *v);
 void vmx_vmcs_exit(struct vcpu *v);
 
-#define CPU_BASED_VIRTUAL_INTR_PENDING  0x00000004
-#define CPU_BASED_USE_TSC_OFFSETING     0x00000008
-#define CPU_BASED_HLT_EXITING           0x00000080
-#define CPU_BASED_INVDPG_EXITING        0x00000200
-#define CPU_BASED_MWAIT_EXITING         0x00000400
-#define CPU_BASED_RDPMC_EXITING         0x00000800
-#define CPU_BASED_RDTSC_EXITING         0x00001000
-#define CPU_BASED_CR8_LOAD_EXITING      0x00080000
-#define CPU_BASED_CR8_STORE_EXITING     0x00100000
-#define CPU_BASED_TPR_SHADOW            0x00200000
-#define CPU_BASED_MOV_DR_EXITING        0x00800000
-#define CPU_BASED_UNCOND_IO_EXITING     0x01000000
-#define CPU_BASED_ACTIVATE_IO_BITMAP    0x02000000
-#define CPU_BASED_ACTIVATE_MSR_BITMAP   0x10000000
-#define CPU_BASED_MONITOR_EXITING       0x20000000
-#define CPU_BASED_PAUSE_EXITING         0x40000000
-#define ACTIVATE_SECONDARY_CONTROLS     0x80000000
+#define CPU_BASED_VIRTUAL_INTR_PENDING        0x00000004
+#define CPU_BASED_USE_TSC_OFFSETING           0x00000008
+#define CPU_BASED_HLT_EXITING                 0x00000080
+#define CPU_BASED_INVDPG_EXITING              0x00000200
+#define CPU_BASED_MWAIT_EXITING               0x00000400
+#define CPU_BASED_RDPMC_EXITING               0x00000800
+#define CPU_BASED_RDTSC_EXITING               0x00001000
+#define CPU_BASED_CR8_LOAD_EXITING            0x00080000
+#define CPU_BASED_CR8_STORE_EXITING           0x00100000
+#define CPU_BASED_TPR_SHADOW                  0x00200000
+#define CPU_BASED_MOV_DR_EXITING              0x00800000
+#define CPU_BASED_UNCOND_IO_EXITING           0x01000000
+#define CPU_BASED_ACTIVATE_IO_BITMAP          0x02000000
+#define CPU_BASED_ACTIVATE_MSR_BITMAP         0x10000000
+#define CPU_BASED_MONITOR_EXITING             0x20000000
+#define CPU_BASED_PAUSE_EXITING               0x40000000
+#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
 extern u32 vmx_cpu_based_exec_control;
 
 #define PIN_BASED_EXT_INTR_MASK         0x00000001
@@ -129,9 +129,6 @@ extern u32 vmx_secondary_exec_control;
     (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)
 #define cpu_has_vmx_tpr_shadow \
     (vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)
-#define cpu_has_vmx_mmap_vtpr_optimization \
-    (cpu_has_vmx_virtualize_apic_accesses && cpu_has_vmx_tpr_shadow)
-
 #define cpu_has_vmx_msr_bitmap \
     (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
 extern char *vmx_msr_bitmap;
index 63af4bfe8f97983f49e1f36fffb1d1592f167e1a..d1bdd3b95e26b33ad5d114f81186c499755b0f9d 100644 (file)
@@ -33,9 +33,6 @@ void vmx_intr_assist(void);
 void vmx_do_resume(struct vcpu *);
 void set_guest_time(struct vcpu *v, u64 gtime);
 
-extern struct page_info *change_guest_physmap_for_vtpr(struct domain *d,
-                                                       int enable_vtpr);
-
 /*
  * Exit Reasons
  */
index 2cd8b27952cd206565262a7975cd1e3b58550991..80e9da6576cb99e3c9971a7a46fca2277f59461f 100644 (file)
@@ -109,12 +109,12 @@ static inline void wrmsrl(unsigned int msr, __u64 val)
 #define MSR_P6_PERFCTR1      0xc2
 
 /* MSRs & bits used for VMX enabling */
-#define MSR_IA32_VMX_BASIC_MSR                  0x480
-#define MSR_IA32_VMX_PINBASED_CTLS_MSR          0x481
-#define MSR_IA32_VMX_PROCBASED_CTLS_MSR         0x482
-#define MSR_IA32_VMX_EXIT_CTLS_MSR              0x483
-#define MSR_IA32_VMX_ENTRY_CTLS_MSR             0x484
-#define MSR_IA32_VMX_MISC_MSR                   0x485
+#define MSR_IA32_VMX_BASIC                      0x480
+#define MSR_IA32_VMX_PINBASED_CTLS              0x481
+#define MSR_IA32_VMX_PROCBASED_CTLS             0x482
+#define MSR_IA32_VMX_EXIT_CTLS                  0x483
+#define MSR_IA32_VMX_ENTRY_CTLS                 0x484
+#define MSR_IA32_VMX_MISC                       0x485
 #define MSR_IA32_VMX_CR0_FIXED0                 0x486
 #define MSR_IA32_VMX_CR0_FIXED1                 0x487
 #define MSR_IA32_VMX_CR4_FIXED0                 0x488